﻿function getDowngaplen() {
    var downgaplen = 0;
    if ($.browser.msie || $.browser.safari || $.browser.opera) {
        return downgaplen = 1;
    }
    else {
        return downgaplen = 8;
    }
}
//初始化对象CSS
function InitObj(obj) {
    obj.css("display", "inline-block");
    obj.css("position", "relative");
    obj.css("padding", "0px");
    obj.css("margin", "0px");
}

function MathPosition(mathObj) {
    this.MathObj = mathObj;
    //设置Math对象样式
    this.MathObj.css("display", "inline-block");
    this.MathObj.css("padding", "0px");
}

MathPosition.prototype = {
    //操作数和操作符的位置和间隙
    Surround: function (scale, objOptions, paramOptions) {
        if (scale == undefined) { scale = 1; } //缩放比例
        var settings = $.extend({
            topgap: 8,
            rightgap: 1,
            downgap: 8,
            leftgap: 1
        }, paramOptions || {});
        var opObj = objOptions.OP; //操作符
        var upObj = objOptions.UP; //上
        var rightObj = objOptions.Right; //右
        var downObj = objOptions.Down; //下
        var leftObj = objOptions.Left; //左
        var fontsize = parseInt(this.MathObj.css("font-size")); //获取数学对象的字体大小
        settings.opheight = opObj.height() / fontsize;

        //设置操作符：==========
        if (opObj == undefined) {
            throw "操作符不能为空！";
        }
        opObj.css("display", "inline-block");
        opObj.css("position", "relative");
        //opObj.css("height", settings.opheight + "em");
        opObj.css("vertical-align", "middle");
        opObj.css("top", "-0.25em"); //修正符号位置，无奈之举
        var opObjHeight = opObj.height();
        var opObjWidth = opObj.width();
        var leftMovedDistance = 0;
        //设置上方操作数位置(分子):===========
        if (upObj != undefined) {
            upObj.css("display", "inline-block");
            upObj.css("position", "relative");
            upObj.css("padding", "0px");
            upObj.css("margin", "0px");
            //动态计算上方操作数的高度，以便设置上方操作数的位置
            var upObjHeight = upObj.height();
            var upObjWidth = upObj.width();
            var upObjHeightEm = 0 - ((upObjHeight / 2) + settings.topgap) / fontsize;
            upObj.css("top", upObjHeightEm + "em");
            var upObjPosition = (opObjWidth / 2 + upObjWidth / 2);
            var upObjPositionem = (upObjPosition / fontsize);
            upObj.css("left", "-" + upObjPositionem + "em");

            leftMovedDistance += upObjWidth;
        }

        //设置右方操作数位置：================
        if (rightObj != undefined) {
            rightObj.css("display", "inline-block");
            rightObj.css("position", "relative");
            rightObj.css("padding", "0px");
            rightObj.css("margin", "0px");
            var rightObjWidth = rightObj.width();
            rightObj.css("left", "-" + (leftMovedDistance - settings.rightgap) / fontsize + "em");
            leftMovedDistance += rightObjWidth;
        }

        //设置下方操作数位置:=================
        if (downObj != undefined) {
            downObj.css("display", "inline-block");
            downObj.css("position", "relative");
            downObj.css("padding", "0px");
            downObj.css("margin", "0px");
            var downObjHeight = downObj.height();
            var downObjWidth = downObj.width();
            var downObjHeightEm = ((downObjHeight / 2) + settings.downgap) / fontsize;
            downObj.css("top", downObjHeightEm + "em");
            var downObjPositionem = ((opObjWidth / 2 + downObjWidth / 2 + leftMovedDistance) / fontsize);
            downObj.css("left", "-" + downObjPositionem + "em");
            leftMovedDistance += downObjWidth;
        }

        //设置左方操作数位置:=================
        var leftObjWidth = 0;
        if (leftObj != undefined) {
            leftObjWidth = leftObj.width();
            leftObj.css("display", "inline-block");
            leftObj.css("position", "relative");
            leftObj.css("padding", "0px");
            leftObj.css("margin", "0px");
            var leftObjPositionem = ((opObjWidth + leftObjWidth + leftMovedDistance + settings.leftgap) / fontsize);
            leftObj.css("left", "-" + leftObjPositionem + "em");
        }
        //设置公式容器的margin

        var mathUpEm = (upObjHeight / 2 + settings.topgap) / fontsize;
        var mathDownEm = (downObjHeight / 2 + settings.downgap) / fontsize;
        var mathObjLeftEm = (leftObjWidth + settings.leftgap) / fontsize;
        var mathRightEm = (upObjWidth + downObjWidth + leftObjWidth - settings.rightgap) / fontsize;
        this.MathObj.css("margin", mathUpEm + "em -" + mathRightEm + "em " + mathDownEm + "em " + mathObjLeftEm + "em");
        this.MathObj.css("font-size", scale + "em");
    },

    //小标注操作数、操作数和操作符的位置
    PowerSurround: function (scale, objOptions, paramOptions) {
        if (scale == undefined) { scale = 1; } //缩放比例
        var settings = $.extend({
            topgap: 8,
            rightgap: 1,
            downgap: 8,
            leftgap: 1
        }, paramOptions || {});
        var opObj = objOptions.OP; //操作符
        var supObj = objOptions.SupOP; //上标注
        var subObj = objOptions.SubOP; //下标注
        var leftSupObj = objOptions.LeftSupOP; //左上标注
        var leftSubObj = objOptions.LeftSubOP; //左下标注
        var upObj = objOptions.UP; //上        
        var rightObj = objOptions.Right; //右        
        var downObj = objOptions.Down; //下
        var leftObj = objOptions.Left; //左
        var fontsize = parseInt(this.MathObj.css("font-size")); //获取数学对象的字体大小
        settings.opheight = opObj.height() / fontsize;
        var maginwidth = 0;
        //设置操作符：==========
        if (opObj == undefined) {
            throw "操作符不能为空！";
        }
        opObj.css("display", "inline-block");
        opObj.css("position", "relative");
        opObj.css("margin", "0px");
        opObj.css("padding", "0px");
        opObj.css("vertical-align", "middle");
        var opObjHeight = opObj.height();
        var opObjWidth = opObj.width();
        var leftMovedDistance = 0;
        var leftWidth = 0;
        var rightWidth = 0;

        //设置下标注
        if (subObj != undefined) {
            InitObj(subObj);
            leftWidth = subObj.width();
            subObj.css("font-size", "0.7em");
            subObj.css("position", "relative");
            subObj.css("top", opObj.height() / 2 / fontsize + "em");
            leftMovedDistance += subObj.width();
        }

        //设置上标注
        if (supObj != undefined) {
            InitObj(supObj);
            supObj.css("font-size", "0.7em");
            supObj.css("position", "relative");
            supObj.css("top", "-" + opObj.height() / 2 / fontsize + "em");
            supObj.css("left", "-" + leftWidth + "px");
            leftMovedDistance += supObj.width();
            if (subObj != undefined) {
                if (subObj.width() > supObj.width()) {
                    maginwidth += subObj.width() - (subObj.width() - supObj.width());
                }
                else {
                    maginwidth += supObj.width() - (supObj.width() - subObj.width());
                }
            }

        }
        //设置左上标注
        if (leftSupObj != undefined) {
            InitObj(leftSupObj);
            leftSupObj.css("font-size", "0.7em");
            leftSupObj.css("position", "relative");
            leftSupObj.css("top", "-0.5em");
            leftWidth = opObjWidth + leftSupObj.width();
            leftSupObj.css("left", "-" + leftWidth + "px");
            leftMovedDistance += leftSupObj.width();
            maginwidth += leftSupObj.width();
        }
        //设置左下标注
        if (leftSubObj != undefined) {
            InitObj(leftSubObj);
            leftSubObj.css("font-size", "0.7em");
            leftSubObj.css("position", "relative");
            leftSubObj.css("top", "0.3em");
            leftWidth = opObjWidth + leftSupObj.width() + leftSubObj.width();
            leftSubObj.css("left", "-" + leftWidth + "px");
            leftMovedDistance += leftSubObj.width();
            maginwidth += leftSubObj.width();
            if (leftSupObj != undefined) {
                if (leftSubObj.width() > leftSupObj.width()) {
                    rightWidth += leftSubObj.width();
                }
                else {
                    rightWidth = leftSupObj.width();
                }
            }
        }
        //设置上方操作数位置(分子):===========
        if (upObj != undefined) {
            upObj.css("display", "inline-block");
            upObj.css("position", "relative");
            upObj.css("padding", "0px");
            upObj.css("margin", "0px");
            //动态计算上方操作数的高度，以便设置上方操作数的位置
            var upObjHeight = upObj.height();
            var upObjWidth = upObj.width();
            var upObjHeightEm = 0 - ((opObjHeight / 2) + settings.topgap) / fontsize;
            upObj.css("top", upObjHeightEm + "em");
            var upObjPosition = (opObjWidth / 2 + upObjWidth / 2);
            var upObjPositionem = (upObjPosition / fontsize);
            upObj.css("left", "-" + upObjPositionem + "em");
            leftMovedDistance += upObjWidth;
        }

        //设置右方操作数位置：================
        if (rightObj != undefined) {
            rightObj.css("display", "inline-block");
            rightObj.css("position", "relative");
            rightObj.css("padding", "0px");
            rightObj.css("margin", "0px");
            var rightObjWidth = rightObj.width();
            rightObj.css("left", "-" + (leftMovedDistance - settings.rightgap) / fontsize + "em");
            leftMovedDistance += rightObjWidth;
        }

        //设置下方操作数位置:=================
        if (downObj != undefined) {
            downObj.css("display", "inline-block");
            downObj.css("position", "relative");
            downObj.css("padding", "0px");
            downObj.css("margin", "0px");
            var downObjHeight = downObj.height();
            var downObjWidth = downObj.width();
            var downObjHeightEm = ((downObjHeight / 2) + settings.downgap) / fontsize;
            downObj.css("top", downObjHeightEm + "em");
            var downObjPositionem = ((opObjWidth / 2 + downObjWidth / 2 + leftMovedDistance) / fontsize);
            downObj.css("left", "-" + downObjPositionem + "em");
            leftMovedDistance += downObjWidth;
        }

        //设置左方操作数位置:=================
        var leftObjWidth = 0;
        if (leftObj != undefined) {
            leftObjWidth = leftObj.width();
            leftObj.css("display", "inline-block");
            leftObj.css("position", "relative");
            leftObj.css("padding", "0px");
            leftObj.css("margin", "0px");
            var leftObjPositionem = ((opObjWidth + leftObjWidth + leftMovedDistance + settings.leftgap) / fontsize);
            leftObj.css("left", "-" + leftObjPositionem + "em");
        }
        //设置公式容器的margin

        //        var mathUpEm = (upObjHeight / 2 + settings.topgap) / fontsize;
        //        var mathDownEm = (downObjHeight / 2 + settings.downgap) / fontsize;
        //        var mathObjLeftEm = (leftObjWidth + settings.leftgap) / fontsize;
        //        var mathRightEm = (upObjWidth + downObjWidth + leftObjWidth - settings.rightgap) / fontsize;
        //        //this.MathObj.css("margin", mathUpEm + "em -" + mathRightEm + "em " + mathDownEm + "em " + mathObjLeftEm + "em");
        this.MathObj.css("margin", "0px -" + maginwidth + "px 0px " + rightWidth + "px");
        this.MathObj.css("font-size", scale + "em");
    },

    RootSurround: function (scale, objOptions, paramOptions) {
        var settings = $.extend({
            topgap: 8,
            rightgap: 1,
            downgap: 8,
            leftgap: 1
        }, paramOptions || {});
        var opObj = objOptions.OP; //操作符
        var bnumObj = objOptions.BnumOP; //底数
        var leftSupObj = objOptions.LeftSupOP; //左上标注
        var fontsize = parseInt(this.MathObj.css("font-size")); //获取数学对象的字体大小
        var bnumheight = bnumObj.height();

        if (opObj == undefined) {
            throw "操作符不能为空！";
        }
        opObj.css("display", "inline-block");
        opObj.css("position", "relative");
        opObj.css("margin", "0px");
        opObj.css("padding", "0px");
        //opObj.css("border", "solid");
        if (bnumheight < 25) {
            opObj.html("<img src='images/genhao.png' />");
        }
        else if (bnumheight > 25 && bnumheight < 50) {
            opObj.html("<img src='images/genhao1.png' />");
        }
        else {
            opObj.html("<img src='images/genhao2.png' />");
        }

        opObj.css("float", "left");
        //opObj.height("25px");
        var opObjHeight = opObj.height();
        var opObjWidth = opObj.width();

        InitObj(bnumObj);
        bnumObj.css("border-top-style", "solid");
        bnumObj.css("border-width", 2 / fontsize + "em");
        //bnumObj.height("21px");
        bnumObj.css("right", "0.1em");
        bnumObj.css("float", "left");
        //bnumObj.css("border", "solid");
        if (leftSupObj != undefined) {
            InitObj(leftSupObj);
            leftSupObj.css("font-size", "0.7em");
            leftSupObj.css("position", "relative");
            leftSupObj.css("top", "-0.5em");
            leftWidth = opObjWidth + leftSupObj.width();
            leftSupObj.css("left", "-" + (opObjWidth + bnumObj.width()) / fontsize + "em");
            //            leftMovedDistance += leftSupObj.width();
            //            maginwidth += leftSupObj.width();
            this.MathObj.css("margin", "0em -" + leftSupObj.width() / fontsize + "em 0em 0em");
            this.MathObj.css("font-size", scale + "em");
        }

    },
    IntegralSurround: function (scale, objOptions, paramOptions) {
        var settings = $.extend({
            topgap: 8,
            rightgap: 1,
            downgap: 8,
            leftgap: 1
        }, paramOptions || {});
        var opObj = objOptions.OP; //操作符
        var rightObj = objOptions.Right; //右
        var supObj = objOptions.SupOP; //上标注
        var subObj = objOptions.SubOP; //下标注
        var upObj = objOptions.UP; //上
        var downObj = objOptions.Down; //下
        var fontsize = parseInt(this.MathObj.css("font-size"));


        if (opObj == undefined) {
            throw "操作符不能为空！";
        }
        opObj.css("display", "inline-block");
        opObj.css("position", "relative");
        opObj.css("margin", "0px");
        opObj.css("padding", "0px");
        opObj.html("<img src='images/jifen.png' />");
        //opObj.css("border", "solid");
        var rightwidth = rightObj.width();
        var fdf = opObj.find("img");
        opObj.find("img").load(function () {
            var opheight = opObj.height();
            var rightheight = rightObj.height();

            InitObj(rightObj);
            //alert(opheight + "\r" + rightheight);

            rightObj.css("top", "-" + (opheight - rightheight) / 2 / fontsize + "em");

            //设置上标注
            if (supObj != undefined) {
                InitObj(supObj);
                supObj.css("font-size", "0.7em");
                supObj.css("top", "-" + (opObj.height() - supObj.height()) + "px");
                supObj.css("left", "-" + rightwidth + "px");
            }
            var tag = 10;
            //设置下标注
            if (subObj != undefined) {
                InitObj(subObj);
                subObj.css("font-size", "0.7em");
                subObj.css("left", "-" + (rightwidth + supObj.width() + tag) + "px");
                rightObj.css("left", "0.5em");
            }
            tag = 5;
            //设置上
            if (upObj != undefined) {
                InitObj(upObj);
                upObj.css("font-size", "0.7em");
                upObj.css("top", "-" + opObj.height() + "px");
                upObj.css("left", "-" + (upObj.width() / 2 + opObj.width() / 2 + rightwidth - tag) + "px");
            }
            //设置下
            if (downObj != undefined) {
                InitObj(downObj);
                downObj.css("font-size", "0.7em");
                downObj.css("top", downObj.height() + "px");
                downObj.css("left", "-" + (rightwidth + upObj.width() + opObj.width() / 2 + downObj.width() / 2 + tag) + "px");
                rightObj.css("left", "0.5em");
            }
        });

        //rightObj.css("border", "solid");
    },
    BracketSurround: function (scale, objOptions, paramOptions) {
        var settings = $.extend({
            topgap: 8,
            rightgap: 1,
            downgap: 8,
            leftgap: 1
        }, paramOptions || {});
        var oplObj = objOptions.OPL; //操作符
        var middleObj = objOptions.Middle; //中间
        var oprObj = objOptions.OPR; //操作符
        var fontsize = parseInt(this.MathObj.css("font-size"));

        var middleheight = middleObj.height();

        if (oplObj == undefined || oprObj == undefined) {
            throw "操作符不能为空！";
        }
        InitObj(oplObj);
        InitObj(oprObj);
        oplObj.html("<img src='images/kuohao1.png' />");
        oprObj.html("<img src='images/kuohao2.png' />");

        oplObj.find("img").height(middleheight);
        oprObj.find("img").height(middleheight);

        oplObj.css("float", "left");
        oprObj.css("float", "left");
        middleObj.css("float", "left");
    }
};

function MathExpression(mathObj) {
    this.MathObj = mathObj;
    this.MathPositionObj = new MathPosition(mathObj);
}

MathExpression.prototype = {
    bracket: function (scale) {
        var oplObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var middleObj = this.MathObj.find(">span:nth-child(2)"); //中间
        var oprObj = this.MathObj.find(">span:nth-child(3)"); //操作符
        var downgaplen = getDowngaplen();
        this.MathPositionObj.BracketSurround(scale, { OPL: oplObj, Middle: middleObj, OPR: oprObj }, { downgap: downgaplen });
    },
    integral3: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var rightObj = this.MathObj.find(">span:nth-child(2)"); //右
        var upObj = this.MathObj.find(">span:nth-child(3)"); //上
        var downObj = this.MathObj.find(">span:nth-child(4)"); //下
        var downgaplen = getDowngaplen();
        this.MathPositionObj.IntegralSurround(scale, { OP: opObj, Right: rightObj, UP: upObj, Down: downObj }, { downgap: downgaplen });
    },
    integral2: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var rightObj = this.MathObj.find(">span:nth-child(2)"); //右
        var supObj = this.MathObj.find(">span:nth-child(3)"); //上标
        var subObj = this.MathObj.find(">span:nth-child(4)"); //下标
        var downgaplen = getDowngaplen();
        this.MathPositionObj.IntegralSurround(scale, { OP: opObj, Right: rightObj, SupOP: supObj, SubOP: subObj }, { downgap: downgaplen });
    },
    integral: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var rightObj = this.MathObj.find(">span:nth-child(2)"); //右
        var downgaplen = getDowngaplen();
        this.MathPositionObj.IntegralSurround(scale, { OP: opObj, Right: rightObj }, { downgap: downgaplen });
    },
    rootandbn: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var bottomObj = this.MathObj.find(">span:nth-child(2)"); //底数
        var leftsupObj = this.MathObj.find(">span:nth-child(3)"); //左上标
        var downgaplen = getDowngaplen();
        this.MathPositionObj.RootSurround(scale, { OP: opObj, BnumOP: bottomObj, LeftSupOP: leftsupObj }, { downgap: downgaplen });
    },
    root: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var bottomObj = this.MathObj.find(">span:nth-child(2)"); //底数
        var downgaplen = getDowngaplen();
        this.MathPositionObj.RootSurround(scale, { OP: opObj, BnumOP: bottomObj }, { downgap: downgaplen });
    },
    //左上下标
    leftsubsup: function (scale) {
        var foundationObj = this.MathObj.find(">span:nth-child(1)"); //底数
        var leftsupObj = this.MathObj.find(">span:nth-child(2)"); //左上标
        var leftsubObj = this.MathObj.find(">span:nth-child(3)"); //左下标
        var downgaplen = getDowngaplen();
        this.MathPositionObj.PowerSurround(scale, { OP: foundationObj, LeftSupOP: leftsupObj, LeftSubOP: leftsubObj }, { downgap: downgaplen });
    },
    //右下标
    sub: function (scale) {
        var foundationObj = this.MathObj.find(">span:nth-child(1)"); //底数
        var subObj = this.MathObj.find(">span:nth-child(2)"); //下标
        var downgaplen = getDowngaplen();
        this.MathPositionObj.PowerSurround(scale, { OP: foundationObj, SubOP: subObj }, { downgap: downgaplen });
    },
    //右上下标
    subsup: function (scale) {
        var foundationObj = this.MathObj.find(">span:nth-child(1)"); //底数
        var subObj = this.MathObj.find(">span:nth-child(2)"); //下标
        var supObj = this.MathObj.find(">span:nth-child(3)"); //上标
        var downgaplen = 0;
        if ($.browser.msie || $.browser.safari || $.browser.opera) {
            downgaplen = 1;
        }
        else {
            downgaplen = 8;
        }
        this.MathPositionObj.PowerSurround(scale, { OP: foundationObj, SupOP: supObj, SubOP: subObj }, { downgap: downgaplen });
    },
    //右上标（幂）
    sup: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var upObj = this.MathObj.find(">span:nth-child(2)"); //上
        var downgaplen = 0;
        if ($.browser.msie || $.browser.safari || $.browser.opera) {
            downgaplen = 1;
        }
        else {
            downgaplen = 8;
        }
        this.MathPositionObj.PowerSurround(scale, { OP: opObj, SupOP: upObj }, { downgap: downgaplen });
    },
    //分数
    frac: function (scale) {
        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var upObj = this.MathObj.find(">span:nth-child(2)"); //上
        var downObj = this.MathObj.find(">span:nth-child(3)"); //下
        var opheight = 0.1;
        var opwidthfix = 10;
        var fontsize = parseInt(this.MathObj.css("font-size"));
        opObj.css("height", opheight + "em"); //可以传参
        var opWidth = Math.max(upObj.width(), downObj.width()) + opwidthfix; //操作符号宽度取分子和分母的最大值然后加10px,可设置为参数
        var opWidthEm = opWidth / fontsize; //操作符相对单位
        //this.MathObj.css("width", opWidthEm + "em"); //修复火狐下的bug:子元素无法撑开父元素
        opObj.css("width", opWidthEm + "em");
        opObj.css("border-left", opWidthEm + "em solid silver");
        var downgaplen = 0;
        if ($.browser.msie || $.browser.safari || $.browser.opera) {
            downgaplen = 1;
        }
        else {
            downgaplen = 8;
        }
        this.MathPositionObj.Surround(scale, { OP: opObj, UP: upObj, Down: downObj }, { downgap: downgaplen });
        opObj.css("width", "0");
        this.MathObj.height(upObj.height() + downObj.height() + opObj.height());
    },
    surround: function (scale) {

        var opObj = this.MathObj.find(">span:nth-child(1)"); //操作符
        var upObj = this.MathObj.find(">span:nth-child(2)"); //上
        var rightObj = this.MathObj.find(">span:nth-child(3)"); //右
        var downObj = this.MathObj.find(">span:nth-child(4)"); //下
        var leftObj = this.MathObj.find(">span:nth-child(5)"); //左
        this.MathPositionObj.Surround(scale, { OP: opObj, UP: upObj, Right: rightObj, Down: downObj, Left: leftObj });

    }
};

(function ($) {
    $.fn.extend({
        formula: function (scale) {
            if (scale == undefined) { scale = 1; }
            var methodName = $(this).attr("math");
            if (methodName == undefined || methodName == "") {
                alert("没有定义表达式！");
                return;
            }
            try {
                $(this).children().each(function () {
                    $(this).children().each(function () {
                        if ($(this).attr("math") != undefined) {
                            $(this).formula(0.8);
                        }
                    });
                });
                var mathExpression = new MathExpression($(this));
                mathExpression[methodName](scale);
            }
            catch (e) { alert(e); }
        }
    });
})(jQuery)



